package com.jule.miaozhuapc.service.impl;

import com.jule.miaozhuapc.controller.wxpayTest.WxCommonUtil;
import com.jule.miaozhuapc.dao.PayConfigDao;
import com.jule.miaozhuapc.dao.RechargeDao;
import com.jule.miaozhuapc.domain.WawaPayConfig;
import com.jule.miaozhuapc.domain.WawaRecharge;
import com.jule.miaozhuapc.domain.WawaUser;
import com.jule.miaozhuapc.service.PingPayService;
import com.jule.miaozhuapc.util.*;
import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.security.util.BigInt;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;


@Service
@Transactional
public class PingPayServiceImpl implements PingPayService {

    @Autowired
    PayConfigDao payConfigDao;
    @Autowired
    RechargeDao rechargeDao;

    private String subject = "喵抓娃娃－喵币充值";
    private String body = "喵抓娃娃平台，用户充值喵币后，通过消耗喵币来兑换抓娃娃的次数";

    private Logger logger = Logger.getLogger(PingPayServiceImpl.class);

    @Override
    public JSONObject createCharge(WawaUser user, Long payConfigId, String channel) {


        WawaPayConfig payConfig = payConfigDao.findbyId(payConfigId);
        // 支付比例是否存在
        if (payConfig == null) {
            return null;
        }
        JSONObject rst = null;

        try {
            //设置 支付方式
            if (channel == null || "".equals(channel)) {
                rst = new JSONObject(new PingPayUtil().createCharge(getChargeOrderNo(""), payConfig.getMoney(), subject, body));
            } else {
                rst = new JSONObject(new PingPayUtil(channel).setExtra(user.getWxOpenId()).createCharge(getChargeOrderNo(""), payConfig.getMoney(), subject, body));

            }
            logger.info(rst);
            if (rst != null && rst.has("order_no")) {
                String order_no = rst.getString("order_no");
                WawaRecharge wawaRecharge = new WawaRecharge();
                wawaRecharge.setOrderNo(order_no);
                wawaRecharge.setStatus(0);
                wawaRecharge.setType(Const.PING_PAY_TYEP_D);
                wawaRecharge.setAddTime(new Date());
                wawaRecharge.setMoney(payConfig.getMoney());
                wawaRecharge.setCoin(payConfig.getCoin());
                wawaRecharge.setUserId(user.getId());
                wawaRecharge.setPayConfigId(payConfigId);
                wawaRecharge.setRemark("充值");
                wawaRecharge.setIsDelete(false);
                wawaRecharge = rechargeDao.insert(wawaRecharge);

                logger.info(new JSONObject(wawaRecharge));
                logger.info(rst);
                return rst;
            }
        } catch (Exception e) {
            e.getMessage();
        }

        return null;
    }


    /**
     *
     * @return
     * @throws Exception
     */
    /**
     * 生成支付订单
     *
     * @param channel 支付方式
     * @return
     * @throws Exception
     */
    private String getChargeOrderNo(String channel) throws Exception {
        //当前年月日
        String newNYR = new DateFormat().getNewNYR();
        // 查询当日订单
        WawaRecharge recharge = rechargeDao.findMaxRecharge();
        //
        String newIndex = "0";
        if (recharge != null && !recharge.getOrderNo().isEmpty() && newNYR.equals(recharge.getOrderNo().substring(1, 9))) {
            newIndex = recharge.getOrderNo().substring(9);
            if (newIndex.length() > 4) {
                newIndex = newIndex.substring(0, 4);
            }
        }
        // D(支付)20171204(年月日)0001(当日订单数)
        String order_no = "D" + newNYR + String.format("%0" + 4 + "d", Integer.parseInt(newIndex) + 1) + new YZRandom().getInviteCode(1) + "_" + channel.substring(0, 2);
        return order_no;
    }

    /**
     * 微信统一支付
     *
     * @param user
     * @param payConfigId
     * @param channel     支付方式
     * @return
     * @throws Exception
     */
    public  SortedMap<Object, Object> wxCharge(WawaUser user, Long payConfigId, String channel) {

        WawaPayConfig payConfig = payConfigDao.findbyId(payConfigId);

        /**
         *  统一支付URL
         */
        final String UNI_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        final String UTF8 = "UTF-8";
        final String notify_url = "https://www.likewawa.com/miaozhuapc/WxPaySucServlet";
        String out_trade_no = new Date().getTime()+"";
        try {
           out_trade_no = getChargeOrderNo(channel);
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("订单生产成失败");
        }
        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
        parameters.put("appid", Const.WAWA_H5_WX_APPID);// 公众账号id
        parameters.put("mch_id", Const.WAWA_H5_WX_PAY_MCH_ID);// 商户号 1493541142
        parameters.put("nonce_str", YZRandom.createNoncestr(32));// 随机字符串
        parameters.put("body", "喵抓娃娃－喵币充值");// 商品描述
        parameters.put("detail", "喵抓娃娃平台，用户充值喵币后，通过消耗喵币来兑换抓娃娃的次数");// 商品详请
        parameters.put("trade_type", channel);// 支付方式
        parameters.put("sign_type", "MD5");// 签名类型 MD5 or HMAC-SHA256
        parameters.put("fee_type", "CNY");// 币种

        parameters.put("out_trade_no", out_trade_no);// 商户订单号
        parameters.put("total_fee", BigDecimal.valueOf(payConfig.getMoney()).multiply(new BigDecimal(100)).setScale(0).toString());// 标价金额
        parameters.put("device_info", "WEB"); //终端
        parameters.put("notify_url", notify_url);// 支付成功回调地址
        parameters.put("spbill_create_ip", "127.0.0.1");// 商户订单号
        parameters.put("openid", user.getWxOpenId());// 当支付方式为 JSAPI 毕传为用户openId
        String sign = WxComUtil.createSignMD5(UTF8, parameters, "fb1a48fdacf44f7e81819196ab62de49");
        parameters.put("sign", sign);
        String reqBody = WxComUtil.getRequestXml(parameters);
        String result = WxCommonUtil.httpsRequestString(UNI_URL, "POST", reqBody);
        logger.info(reqBody);
        logger.info(result);
        Map<String, String> map = new HashMap<String, String>();
        try {
            map = WxComUtil.doXMLParse(result);
            logger.info("------------------code_url=" + map.get("code_url") + ";      result_code=" + map.get("code_url") + "------------------------------");
        } catch (Exception e) {
            logger.error("doXMLParse()--error", e);
        }
        String returnCode = map.get("return_code");
        String resultCode = map.get("result_code");
        // 订单创建成功
        if (returnCode.equalsIgnoreCase("SUCCESS") && resultCode.equalsIgnoreCase("SUCCESS")) {
            String order_no = parameters.get("out_trade_no").toString();
            WawaRecharge wawaRecharge = new WawaRecharge();
            wawaRecharge.setOrderNo(order_no);
            wawaRecharge.setStatus(0);
            wawaRecharge.setType(Const.PING_PAY_TYEP_D);
            wawaRecharge.setAddTime(new Date());
            wawaRecharge.setMoney(payConfig.getMoney());
            wawaRecharge.setCoin(payConfig.getCoin());
            wawaRecharge.setUserId(user.getId());
            wawaRecharge.setPayConfigId(payConfigId);
            wawaRecharge.setRemark("充值");
            wawaRecharge.setIsDelete(false);
            wawaRecharge = rechargeDao.insert(wawaRecharge);

            logger.info(new JSONObject(wawaRecharge));
            logger.info(map.toString());

            SortedMap<Object, Object> web_parameters = new TreeMap<Object, Object>();

            web_parameters.put("appId", Const.WAWA_H5_WX_APPID);
            web_parameters.put("timeStamp", (new Date().getTime()+"").substring(0,10));
            web_parameters.put("nonceStr", YZRandom.createNoncestr(32));
            web_parameters.put("package", "prepay_id="+map.get("prepay_id"));
            web_parameters.put("signType", "MD5");
            web_parameters.put("paySign", WxComUtil.createSignMD5(UTF8, web_parameters, "fb1a48fdacf44f7e81819196ab62de49"));
            return web_parameters;
        }
        return null;
    }

    @Override
    public SortedMap<Object, Object> wxS1Charge(String openId, Long payConfigId, String channel, Long s1UserId) {

        Double money = null;
        /**
         *  拉取服务器APP的充值比例
         */
            String pays1Url = "https://likewawa.com/miaozhua/v1/user/getPayConfig";
            try {
                JSONObject payS1 = LYHttpRequestUtil.sendGet(pays1Url, null);
                logger.info(payS1);
                if (payS1 != null ){
                    JSONArray arr  = payS1.getJSONArray("pays");
                    for(int i = 0 ; i < arr.length(); i++){
                        if (arr.getJSONObject(i).get("payConfigId").toString().equals(payConfigId.toString())){
                            money = Double.parseDouble(arr.getJSONObject(i).get("money").toString());
                            break;
                        }
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
                return null;
            }

        logger.info("钱 " + money);
            //FIXME
        // money = 0.01;
        /**
         *  统一支付URL
         */
        final String UNI_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        final String UTF8 = "UTF-8";
        // 通知APP服务器
        // FIXME likewawa.com
        final String notify_url = "https://likewawa.com/miaozhua/s1/wxpay/"+s1UserId+"/"+ payConfigId;
        String out_trade_no = new Date().getTime()+"";
        try {
            out_trade_no = getChargeOrderNo(channel)+ new Date().getTime();
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("订单生产成失败");
        }
        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
        parameters.put("appid", Const.WAWA_H5_WX_APPID);// 公众账号id
        parameters.put("mch_id", Const.WAWA_H5_WX_PAY_MCH_ID);// 商户号 1493541142
        parameters.put("nonce_str", YZRandom.createNoncestr(32));// 随机字符串
        parameters.put("body", "喵抓娃娃－喵币充值");// 商品描述
        parameters.put("detail", "喵抓娃娃平台，用户充值喵币后，通过消耗喵币来兑换抓娃娃的次数");// 商品详请
        parameters.put("trade_type", channel);// 支付方式
        parameters.put("sign_type", "MD5");// 签名类型 MD5 or HMAC-SHA256
        parameters.put("fee_type", "CNY");// 币种

        parameters.put("out_trade_no", out_trade_no);// 商户订单号
        parameters.put("total_fee", BigDecimal.valueOf(money).multiply(new BigDecimal(100)).setScale(0).toString());// 标价金额
        parameters.put("device_info", "WEB"); //终端
        parameters.put("notify_url", notify_url);// 支付成功回调地址
        parameters.put("spbill_create_ip", "127.0.0.1");// 商户订单号
        parameters.put("openid", openId);// 当支付方式为 JSAPI 毕传为用户openId
        String sign = WxComUtil.createSignMD5(UTF8, parameters, "fb1a48fdacf44f7e81819196ab62de49");
        parameters.put("sign", sign);
        String reqBody = WxComUtil.getRequestXml(parameters);
        String result = WxCommonUtil.httpsRequestString(UNI_URL, "POST", reqBody);
        logger.info(reqBody);
        logger.info(result);
        Map<String, String> map = new HashMap<String, String>();
        try {
            map = WxComUtil.doXMLParse(result);
            logger.info("------------------code_url=" + map.get("code_url") + ";      result_code=" + map.get("code_url") + "------------------------------");
        } catch (Exception e) {
            logger.error("doXMLParse()--error", e);
        }
        String returnCode = map.get("return_code");
        String resultCode = map.get("result_code");
        // 订单创建成功
        if (returnCode.equalsIgnoreCase("SUCCESS") && resultCode.equalsIgnoreCase("SUCCESS")) {
            logger.info(map.toString());

            SortedMap<Object, Object> web_parameters = new TreeMap<Object, Object>();

            web_parameters.put("appId", Const.WAWA_H5_WX_APPID);
            web_parameters.put("timeStamp", (new Date().getTime()+"").substring(0,10));
            web_parameters.put("nonceStr", YZRandom.createNoncestr(32));
            web_parameters.put("package", "prepay_id="+map.get("prepay_id"));
            web_parameters.put("signType", "MD5");
            web_parameters.put("paySign", WxComUtil.createSignMD5(UTF8, web_parameters, "fb1a48fdacf44f7e81819196ab62de49"));
            return web_parameters;
        }
        return null;
    }
}
